import  Round from '../basics/Round.js'
import  Wan from '../utils/Wan.js'
import Block from "../basics/Block.js";
import  Row from '../basics/Row.js'


import {
    BASE_INDEX,
    WAN_INDEX,
    DEFINE_INDEX
}   from "./IndexType.js"
/**
 * 链包
 * 一个链表通常包括,一万个wan
 *
 */

export default class Chr{

    /**
     * 第一个块是用来装载基本信息，
     * 比如，这个模块叫什么，
     * 目录起始块到结束块，（通常目录丢到最后）
     */
    constructor( index = 0,
                 previousHash = '0',
                 timestamp = new Date().getTime() / 1000,
                 data = 'none',
                 hash = '',
                 nonce = 0){
        let buff=new Uint8Array(1250)
        this.list=[ buff];
        this.rounds=[];

        this.index = index
        this.previousHash = previousHash.toString()
        this.timestamp = timestamp
        this.data = data
        this.hash = hash.toString()
        this.nonce = nonce

    }






    static get genesis () {
        return new Block(
        )
    }

    /**
     *  加载 数据
     * @param data
     */
    loadData(data){
        let _this=this;
        let length=0;
        this.rounds=[];
        let buff= new Uint8Array(data);
        let listWan= Wan.buffToWans(buff);
        _this.list=listWan;

        this.analysisIndexes();   // 解析 索引
    }
    /**
     * 获取全部数据
     * @returns {uint8array[]|*[]}
     */
    outData(){
        let _this=this;
        let suoyin=1

        let rounds=this.rounds;
        let newpath =new Round();
        let block =new Block();
        let buff=new Uint8Array(1250)
        let resList=[buff];
        /**
         * 查找临时文件里面有没有内容。
         * 如果有  从文件里面直接导出数据；
         * 如果 没有从list里面读取文件。
         */
        for(let i=0;i<rounds.length;i++){
            let round=rounds[i];
            let length=resList.length;
            let fileBuff= round.outData();
            let fileWan= Wan.buffToWans(fileBuff);
            resList.push(...fileWan)
            block.addRow(new Row(length, length+fileWan.length,null,WAN_INDEX))

        }
        newpath.addBlock(block)

        /**
         * 保存目录数据
         * 保存索引
         * 输出数据
         */

        let resListLength=resList.length;
        let pathsBuff=newpath.outData();
        let pathWan=   Wan.buffToWans(pathsBuff);
        resList.push(...pathWan)
        let file =new Round();
        let  block1=new Block();
        block1.addRow(new Row(resListLength,(resListLength+pathWan.length),null,BASE_INDEX))
        file.addData(null,null,null,block1);
        let wan= Wan.buffToWans(file.outData()) ;
        resList[0]=wan[0];
        for(let i=resList.length;i<10000;i++){
            resList.push(buff)
        }
        let resBuff=Wan.blocksToBuff(resList)
        return resBuff;
    }
    /**
     * 解析索引
     * @returns {*|number|void}
     */
    analysisHead(RoundId,WanId,RowId,dataThis){
        this.headRow= dataThis.list[0]
    }
    /**
     * 解析目录
     * @returns {*|number|void}
     */
    analysisIndexes(){
        let headWan   = this.list[0];
        let head=new Round();
        head.loadData(headWan);
        let pathRow= head.find(1).find(1) ;
        let pathWan=this.list.slice(parseInt(pathRow.find(1)),parseInt(pathRow.find(2)));
        let file=new Round();
        file.loadData(Wan.blocksToBuff(pathWan));

        for(let i=0;i<file.list.length;i++){
            let row= file.find(i+1)
            let round=new Round();
            let data2=this.list.slice(parseInt(row.find(1)),parseInt(row.find(2)));
            round.loadData(Wan.blocksToBuff(data2))
            this.rounds.push(round)
        }

    }

    /**
     *
     * @param RoundId
     * @param BlockId
     * @param RowsId
     * @param data
     * @returns {number|*}
     */
    addData(fileId,blockId,rowsId,data){
        if(fileId!==null){
            if(!this.files[fileId]){
                let file= this.findRound(fileId);
                this.files[fileId]=file;

            }
            return  this.files[fileId].addData(fileId,blockId,rowsId,data)

        }else {
            let block =new Block();

            let length=this.list.length;
            let wan=  Wan.buffToWans(data.outData())
            let path=new Row(length, length+wan.length,null,2)
            block.addData(null,null,null,path)
            let index= this.paths.addData(0,null,null,block)

            this.list.push(...wan);
            return index;
        }

    }



}
